﻿
using System.Drawing;
using System.Reflection;

namespace System.Windows.Forms
{
    /// <summary>
    /// 窗体相关静态方法
    /// </summary>
    public static class ExForm
    {
        #region 由控件创建窗体
        /// <summary>
        /// 使用控件创建窗体
        /// </summary>
        /// <param name="control">控件【NotNull】</param>
        /// <param name="title">窗体标题</param>
        /// <param name="name">窗体名称 null表示标题与名称一致</param>
        /// <returns>窗体对象</returns>
        public static Form CreateToolForm(this Control control, string title = null, string name = null)
        {
            Form form = new Form();
            form.Text = title ?? control.GetType().Name;
            form.Name = name ?? form.Text;
            form.SizeGripStyle = SizeGripStyle.Hide;
            form.Controls.Add(control);
            control.Location = new System.Drawing.Point(0, 0);
            form.ClientSize = new System.Drawing.Size(control.Size.Width, control.Size.Height);
            form.StartPosition = FormStartPosition.CenterScreen;
            control.Dock = DockStyle.Fill;
            return form;
        }
        #endregion

        #region 强制设置双缓冲
        /// <summary>
        /// 设置启用双缓冲
        /// </summary>
        /// <param name="control">需要设置双缓冲的对象</param>
        public static void ForceSetDoubleBuffered(this Control control)
        {
            if (control == null) return;
            if (control is Form)
            {
                var methodInfo = typeof(Control).GetMethod("SetStyle");
                methodInfo.Invoke(control, new object[]
                {
                    ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer,
                    true
                });
            }

            //通过反射获取非public属性对象
            var propertyInfo = typeof(Control).GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
            SetDoubleBuffered(control, propertyInfo);
        }

        /// <summary>
        /// 查找子级控件 设置双缓冲
        /// </summary>
        /// <param name="ctl">要查找下级控件的Control</param>
        /// <param name="propertyInfo">PropertyInfo对象</param>
        private static void SetDoubleBuffered(
            Control ctl,
            PropertyInfo propertyInfo)
        {
            propertyInfo.SetValue(ctl, true, null);
            foreach (Control rootCtl in ctl.Controls)
            {
                SetDoubleBuffered(rootCtl, propertyInfo);
            }
        }
        #endregion
    }
}
